// Package httpd provides the HTTP server for accessing the distributed key-value store.
// It also provides the endpoint for other nodes to join an existing cluster.
package httpd

import (
	"github.com/goccy/go-json"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
)

// App provides HTTP service.
type App struct {
	addr    string
	dataDir string
	svc     *Service
}

// New returns an uninitialized HTTP service.
func New(addr string, dataDir string) *App {
	return &App{
		addr:    addr,
		svc:     NewService(dataDir),
		dataDir: dataDir,
	}
}

// Start starts the service.
func (s *App) Start() error {
	r := fiber.New(fiber.Config{
		JSONEncoder: json.Marshal,
		JSONDecoder: json.Unmarshal,
	})
	r.Use(cors.New())
	r.Use(RequestLog())
	// r.MaxMultipartMemory = 8 << 20 // 8 MiB
	s3 := r.Group("/s3") /*, S3Interceptor(SystemConfig{
		Username: "minioadmin",
		Password: "minioadmin",
	})*/
	{
		// 桶列表
		s3.Get("/", s.listBucket)
		// 获取文件列表
		s3.Get("/:bucket/", s.getBucket)
		// 桶详情
		s3.Head("/:bucket/", s.headBucket)
		// 创建桶
		s3.Put("/:bucket/", s.createBucket)
		// 删除桶
		s3.Delete("/:bucket/", s.deleteBucket)
		// 文件分片初始化 or 合并分片
		s3.Post("/:bucket/:object/*", s.initChunkOrCombineChunk)
		// 文件详情
		s3.Head("/:bucket/:object/*", s.headObject)
		// 文件上传 or 分片上传
		s3.Put("/:bucket/:object/*", s.uploadFileOrUploadChunk)
		// 文件删除
		s3.Delete("/:bucket/:object/*", s.deleteFile)
		// 文件下载
		s3.Get("/:bucket/:object/*", s.getFile)
	}

	return r.Listen(s.addr)
}
